/**
	License:		Artistic license 2.0 (see license.txt, also available online at http://www.perlfoundation.org/artistic_license_2_0)
	Authors:		OrbitalLab (http://www.orbitallab.ru/moonglide/), 2007-2009

	File:			RespMesh.d
	Description:	mesh generation
	Date:			13.11.2007 by Jurec
*/

module moonglide.resources.resproc.mesh.ResPMesh;

import
	moonglide.resources.resobjects.lowlevel.ResMesh,
	moonglide.resources.Management;

import tango.math.Math : PI;


void genMeshTangentSpace( ref CResMesh Mesh )
{
	int i1,i2,i3;
	Vector3d sdir;
	Vector3d tdir;

	Mesh.fields["Tangent"].SetLength( Mesh.fields["Vertex"].GetLength );
	Mesh.fields["BiNormal"].SetLength( Mesh.fields["Vertex"].GetLength );
	Vector3d[] tan1, tan2;
	tan1.length = tan2.length = Mesh.fields["Vertex"].GetLength;

	for( int i=0; i < tan1.length; ++i )
	{
		tan1[i].set(0,0,0);
		tan2[i].set(0,0,0);
	}


	for( int i=0; i < Mesh.fields["Index"].GetLength; i+=3 )
	{
   		i1 = Mesh.fields["Index"].data.UInt[i];
    	i2 = Mesh.fields["Index"].data.UInt[i+1];
    	i3 = Mesh.fields["Index"].data.UInt[i+2];

		Vector3f* v1 = &Mesh.fields["Vertex"].data.Vec3[i1];
		Vector3f* v2 = &Mesh.fields["Vertex"].data.Vec3[i2];
		Vector3f* v3 = &Mesh.fields["Vertex"].data.Vec3[i3];
		Vector2f* w1 = &Mesh.fields["TexCoord"].data.Vec2[i1];
		Vector2f* w2 = &Mesh.fields["TexCoord"].data.Vec2[i2];
		Vector2f* w3 = &Mesh.fields["TexCoord"].data.Vec2[i3];

		float x1 = v2.x - v1.x;
		float x2 = v3.x - v1.x;
		float y1 = v2.y - v1.y;
		float y2 = v3.y - v1.y;
		float z1 = v2.z - v1.z;
		float z2 = v3.z - v1.z;
		float s1 = w2.x - w1.x;
		float s2 = w3.x - w1.x;
		float t1 = w2.y - w1.y;
		float t2 = w3.y - w1.y;
		float r = 1.0f / (s1 * t2 - s2 * t1);
		sdir.set((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
		tdir.set((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);

		tan1[i1] += sdir;
		tan1[i2] += sdir;
		tan1[i3] += sdir;
		tan2[i1] += tdir;
		tan2[i2] += tdir;
		tan2[i3] += tdir;
	}

	Vector3f* nor, tan, bin;
	Vector3f _t1,_t2;
	float mull;

	for (int a = 0; a < Mesh.fields["Vertex"].GetLength; a++)
	{
		nor = &Mesh.fields["Normal"].data.Vec3[a];
		tan = &Mesh.fields["Tangent"].data.Vec3[a];
		bin = &Mesh.fields["BiNormal"].data.Vec3[a];
		_t1.set( tan1[a].x, tan1[a].y, tan1[a].z );
		_t2.set( tan2[a].x, tan2[a].y, tan2[a].z );

		*tan = ( _t1 - *nor * dp( *nor , _t1 ) );
		tan.normalize;
		mull = dp(cp(*nor , _t1) , _t2) < 0.0F ? -1.0F : 1.0F;
		*bin = cp( *nor, *tan ) * mull;
	}

}


//================================================================
/// empty mesh
//================================================================
CResMesh genMeshEmpty()
{
	CResMesh pMesh = CResMesh( "meshEmpty" );

	pMesh.fields["Vertex"].data.Vec3 = [];
	pMesh.fields[ "Index" ].data.UInt =[];

	return pMesh;
}


//================================================================
/// triple lines aka axises
//================================================================
CResMesh genMeshAxis( float sizeAxis = 0.0f)
{
	CResMesh pMesh = CResMesh( "meshAxis" );

	pMesh.fields["Vertex"].data.Vec3 =
	[
		Vector3f( 0.1f, 0.0f, 0.0f ),
		Vector3f( -0.1f, 0.0f, 0.0f ),
		Vector3f( 0.0f, sizeAxis, 0.0f ),
		Vector3f( 0.0f, 0.0f, sizeAxis ),
		Vector3f( 0.0f, 0.0f, 0.1f ),
		Vector3f( 0.0f, 0.0f, -0.1f ),
		Vector3f( sizeAxis, 0.0f, 0.0f )
	];

	pMesh.fields[ "Index" ].data.UInt =
	[
		0, 1, 2,	0, 2, 1,	0, 1, 3,
		0, 3, 1,	4, 5, 6,	4, 6, 5
	];

	return pMesh;
}

//================================================================
/// simple cube. Very damn' simple damn' cube.
//================================================================
CResMesh genMeshCube( Vector3f size )
{
	CResMesh pMesh = CResMesh( "Cube" );

	pMesh.fields["Vertex"].data.Vec3 =
	[
		Vector3f( size.x, size.y, size.z ),
		Vector3f( -size.x, size.y, size.z ),
		Vector3f( -size.x, size.y, -size.z ),
		Vector3f( size.x, size.y, -size.z ),
		Vector3f( size.x, -size.y, size.z ),
		Vector3f( -size.x, -size.y, -size.z ),
		Vector3f( -size.x, -size.y, size.z ),
		Vector3f( size.x, -size.y, -size.z )
	];

	pMesh.fields[ "Index" ].data.UInt =
	[
		0, 2, 1,	0, 3, 2,
		4, 6, 5,	4, 5, 7,
		7, 2, 3,	7, 5, 2,
		4, 0, 1,	4, 1, 6,
		7, 3, 0,	7, 0, 4,
		6, 1, 2,	6, 2, 5
	];

	return pMesh;
}

//================================================================
/// cube with normals. Monstrous, helas...
//================================================================
CResMesh genMeshCubeNor( Vector3f size )
{
	CResMesh pMesh = CResMesh( "CubeNor" );
	pMesh.fields[ "Index" ].data.UInt.length = 36;

	for( uint i = 0; i < 36; ++i )
		pMesh.fields[ "Index" ].data.UInt[i] = i;

	pMesh.fields["Normal"].data.Vec3 =
	[
		Vector3f( 0, 1, 0 ), Vector3f( 0, 1, 0 ), Vector3f( 0, 1, 0 ),
		Vector3f( 0, 1, 0 ), Vector3f( 0, 1, 0 ), Vector3f( 0, 1, 0 ),

		Vector3f( 0, -1, 0 ), Vector3f( 0, -1, 0 ), Vector3f( 0, -1, 0 ),
		Vector3f( 0, -1, 0 ), Vector3f( 0, -1, 0 ), Vector3f( 0, -1, 0 ),

		Vector3f( 0, 0, -1 ), Vector3f( 0, 0, -1 ), Vector3f( 0, 0, -1 ),
		Vector3f( 0, 0, -1 ), Vector3f( 0, 0, -1 ), Vector3f( 0, 0, -1 ),
		Vector3f( 0, 0, 1 ), Vector3f( 0, 0, 1 ), Vector3f( 0, 0, 1 ),
		Vector3f( 0, 0, 1 ), Vector3f( 0, 0, 1 ), Vector3f( 0, 0, 1 ),

		Vector3f( 1, 0, 0 ), Vector3f( 1, 0, 0 ), Vector3f( 1, 0, 0 ),
		Vector3f( 1, 0, 0 ), Vector3f( 1, 0, 0 ), Vector3f( 1, 0, 0 ),

		Vector3f( -1, 0, 0 ), Vector3f( -1, 0, 0 ), Vector3f( -1, 0, 0 ),
		Vector3f( -1, 0, 0 ), Vector3f( -1, 0, 0 ), Vector3f( -1, 0, 0 )
	];

	pMesh.fields["TexCoord"].data.Vec2 =
	[
		Vector2f( 1, 1 ), Vector2f( 0, 0 ), Vector2f( 0, 1 ),
		Vector2f( 1, 1 ), Vector2f( 1, 0 ), Vector2f( 0, 0 ),

		Vector2f( 1, 1 ), Vector2f( 0, 1 ), Vector2f( 0, 0 ),
		Vector2f( 1, 1 ), Vector2f( 0, 0 ), Vector2f( 1, 0 ),

		Vector2f( 1, 0 ), Vector2f( 0, 1 ), Vector2f( 1, 1 ),
		Vector2f( 1, 0 ), Vector2f( 0, 0 ), Vector2f( 0, 1 ),

		Vector2f( 1, 0 ), Vector2f( 1, 1 ), Vector2f( 0, 1 ),
		Vector2f( 1, 0 ), Vector2f( 0, 1 ), Vector2f( 0, 0 ),

		Vector2f( 0, 0 ), Vector2f( 1, 0 ), Vector2f( 1, 1 ),
		Vector2f( 0, 0 ), Vector2f( 1, 1 ), Vector2f( 0, 1 ),

		Vector2f( 0, 1 ), Vector2f( 1, 1 ), Vector2f( 1, 0 ),
		Vector2f( 0, 1 ), Vector2f( 1, 0 ), Vector2f( 0, 0 )
	];

	pMesh.fields["Vertex"].data.Vec3 =
	[
		Vector3f( size.x, size.y, size.z ),
		Vector3f( -size.x, size.y, -size.z ),
		Vector3f( -size.x, size.y, size.z ),
		Vector3f( size.x, size.y, size.z ),
		Vector3f( size.x, size.y, -size.z ),
		Vector3f( -size.x, size.y, -size.z ),

		Vector3f( size.x, -size.y, size.z ),
		Vector3f( -size.x, -size.y, size.z ),
		Vector3f( -size.x, -size.y, -size.z ),
		Vector3f( size.x, -size.y, size.z ),
		Vector3f( -size.x, -size.y, -size.z ),
		Vector3f( size.x, -size.y, -size.z ),

		Vector3f( size.x, -size.y, -size.z ),
		Vector3f( -size.x, size.y, -size.z ),
		Vector3f( size.x, size.y, -size.z ),
		Vector3f( size.x, -size.y, -size.z ),
		Vector3f( -size.x, -size.y, -size.z ),
		Vector3f( -size.x, size.y, -size.z ),

		Vector3f( size.x, -size.y, size.z ),
		Vector3f( size.x, size.y, size.z ),
		Vector3f( -size.x, size.y, size.z ),
		Vector3f( size.x, -size.y, size.z ),
		Vector3f( -size.x, size.y, size.z ),
		Vector3f( -size.x, -size.y, size.z ),

		Vector3f( size.x, -size.y, -size.z ),
		Vector3f( size.x, size.y, -size.z ),
		Vector3f( size.x, size.y, size.z ),
		Vector3f( size.x, -size.y, -size.z ),
		Vector3f( size.x, size.y, size.z ),
		Vector3f( size.x, -size.y, size.z ),

		Vector3f( -size.x, -size.y, size.z ),
		Vector3f( -size.x, size.y, size.z ),
		Vector3f( -size.x, size.y, -size.z ),
		Vector3f( -size.x, -size.y, size.z ),
		Vector3f( -size.x, size.y, -size.z ),
		Vector3f( -size.x, -size.y, -size.z )
	];

	genMeshTangentSpace( pMesh );
	return pMesh;
}

//================================================================
/// sphere
//================================================================
CResMesh genMeshSphere( float rad, uint tesselation )
{
	CResMesh pMesh = CResMesh( "Sphere" );

	Vector3f[]	vertices;
	Vector3f[]	normals;
	Vector2f[]	texCoords;
	uint[]		indexes;

	const real X = 0.525731112119133606;
	const real Z = 0.850650808352039932;

	Vector3r[] srcdata =
	[
		Vector3r( -X, 0.0, Z ), Vector3r( X, 0.0, Z ), Vector3r( -X, 0.0, -Z ), Vector3r( X, 0.0, -Z ),
    	Vector3r( 0.0, Z, X ), Vector3r( 0.0, Z, -X ), Vector3r( 0.0, -Z, X ), Vector3r( 0.0, -Z, -X ),
		Vector3r( Z, X, 0.0 ), Vector3r( -Z, X, 0.0 ), Vector3r( Z, -X, 0.0 ), Vector3r( -Z, -X, 0.0 )
	];

	indexes =
	[
		1, 4 ,0,
		4, 9, 0,
		4, 5, 9,
		8, 5, 4,
		1, 8, 4,
		1, 10, 8,
		10, 3, 8,
		8, 3, 5,
		3, 2, 5,
		3, 7, 2,
		3, 10, 7,
		10, 6, 7,
		6, 11, 7,
		6, 0, 11,
		6, 1, 0,
		10, 1, 6,
		11, 0, 9,
		2, 11, 9,
		5, 2, 9,
		11, 2, 7
	];

	for( uint i = 0; i < tesselation; i++ )		// divide each triangle to 4 new triangles:
	{
		/* 1, 2, 3 - vertices of old triangle ( which is going to be tesselated ),
			t1, t2, t3 - new vertices for each triangle, so it is tesselated to 4 lesser triangles,
			1-2, 2-3, 3-1 - lines of old triangle that will hold new vertex.

			New triangles after tesselation: 1-t1-t3 (left), t1-2-t2 (up), t3-t2-3 (right), t3-t1-t2 (center)
			   2
			  /  \
			 /    \
			/      \
		  t1        t2
		  /          \
		 /            \
	    1_____ t3 _____3

		*/

		if( i == 0 )
			traceLog.trace( Format( "Icosahedron tesselation started. Source triangles: {}, source vertices: {}",
				indexes.length / 3, srcdata.length ));

		struct STriangle
		{
			uint ind1, ind2, ind3;				// index of vertices
			uint l1, l2, l3;						// index of lines
		}

		struct SLine
		{
			uint ind1, ind2, newvertind;
			Vector3r newVert;
		}

		STriangle[] triangles;
		SLine[] lines;

		triangles.length = indexes.length / 3;
		lines.length = indexes.length; // reserve space for quick resize
		lines.length = 0;

		STriangle tmptri;
		SLine tmpln;

		uint checkresult;

//-------------- func of search for duplicate lines -----------------------------------------
		uint SearchDuplicateLine( SLine search_line )
		{
			foreach( index, line; lines )
			{
				if( (line.ind1 == search_line.ind1) && (line.ind2 == search_line.ind2)
					|| (line.ind1 == search_line.ind2) && (line.ind2 == search_line.ind1) )
					return index;
			}

			return 0;
		}
//----------------------------------------------------------------------------------------------

// 1. index to triangles
// 2. triangles to lines, remove duplicates
		for( uint ind = 0, tri = 0; ind < indexes.length; ind += 3, tri++ )
		{
			tmptri.ind1 = indexes[ind];
			tmptri.ind2 = indexes[ind+1];
			tmptri.ind3 = indexes[ind+2];
// line 1 ---------------------------------------------------
			tmpln.ind1 = tmptri.ind1;
			tmpln.ind2 = tmptri.ind2;
			checkresult = SearchDuplicateLine( tmpln );

			if( checkresult == 0 )	// not found
			{
				tmptri.l1 = lines.length;
				lines ~= tmpln;
			}
			else			// found, checkresult contains index
				tmptri.l1 = checkresult;
// line 2 ---------------------------------------------------
			tmpln.ind1 = tmptri.ind2;
			tmpln.ind2 = tmptri.ind3;
			checkresult = SearchDuplicateLine( tmpln );

			if( checkresult == 0 )	// not found
			{
				tmptri.l2 = lines.length;
				lines ~= tmpln;
			}
			else			// found, checkresult contains index
				tmptri.l2 = checkresult;
// line 3 ---------------------------------------------------
			tmpln.ind1 = tmptri.ind3;
			tmpln.ind2 = tmptri.ind1;
			checkresult = SearchDuplicateLine( tmpln );

			if( checkresult == 0 )	// not found
			{
				tmptri.l3 = lines.length;
				lines ~= tmpln;
			}
			else			// found, checkresult contains index
				tmptri.l3 = checkresult;

			triangles[tri] = tmptri;
		}

// 3. tesselation, adding new vertices
		Vector3r v1, v2;

		foreach( ref line; lines )
		{
			v1 = srcdata[ line.ind1 ];
			v2 = srcdata[ line.ind2 ];

			line.newVert.set(
				v1.x + ( v2.x - v1.x) * 0.5,
				v1.y + ( v2.y - v1.y) * 0.5,
				v1.z + ( v2.z - v1.z) * 0.5 );
			line.newVert.normalize();

			line.newvertind = srcdata.length;
			srcdata ~= line.newVert;
		}

		STriangle	newtri1, newtri2, newtri3;
		uint		multindex;

		indexes.length = triangles.length * 4 * 3;

// 4. triangles reprocess, adding new triangles
// 5. triangles to indexes
		foreach( index, ref triangle; triangles )
		{
			// new upper
			newtri1.ind1 = lines[ triangle.l1 ].newvertind;
			newtri1.ind2 = triangle.ind2;
			newtri1.ind3 = lines[ triangle.l2 ].newvertind;

			// new right
			newtri2.ind1 = lines[ triangle.l3 ].newvertind;
			newtri2.ind2 = lines[ triangle.l2 ].newvertind;
			newtri2.ind3 = triangle.ind3;

			// new center
			newtri3.ind1 = lines[ triangle.l3 ].newvertind;
			newtri3.ind2 = lines[ triangle.l1 ].newvertind;
			newtri3.ind3 = lines[ triangle.l2 ].newvertind;

			// new left = change indexes for current (already tesselated big) trinagle
			triangle.ind2 = lines[ triangle.l1 ].newvertind;
			triangle.ind3 = lines[ triangle.l3 ].newvertind;

			multindex = index * 12;

			// add indexes of changed triangle and 3 new triangles to pMesh' index array
			indexes[ multindex ]		= triangle.ind1;
			indexes[ multindex + 1 ]	= triangle.ind2;
			indexes[ multindex + 2 ]	= triangle.ind3;

			indexes[ multindex + 3 ]	= newtri1.ind1;
			indexes[ multindex + 4 ]	= newtri1.ind2;
			indexes[ multindex + 5 ]	= newtri1.ind3;

			indexes[ multindex + 6 ]	= newtri2.ind1;
			indexes[ multindex + 7 ]	= newtri2.ind2;
			indexes[ multindex + 8 ]	= newtri2.ind3;

			indexes[ multindex + 9 ]	= newtri3.ind1;
			indexes[ multindex + 10 ]	= newtri3.ind2;
			indexes[ multindex + 11 ]	= newtri3.ind3;
		}

		traceLog.trace( Format( "Icosahedron tesselation in progress. Pass {}, triangles: {}, vertices: {}",
			i + 1, triangles.length * 4, srcdata.length ));
	}
//----------------- end tesselation loop --------------------------------------------------

	vertices.length = normals.length = texCoords.length = srcdata.length;

	foreach( index, vect; srcdata )
	{
		normals[ index ]	= vect.toVector3f();
		vertices[ index ]	= vect.toVector3f() * rad;

		static float x, y, angle;

		if( vect.x > 0 )
			if( vect.z >= 0 )	// 1st quarter
				angle = 90.0 - atan( vect.x / vect.z ) * 180 / PI;
			else				// 4th quarter
				angle = 270.0 + atan( vect.x / -vect.z ) * 180 / PI;
		else
			if( vect.z >= 0 )	// 2nd quarter
				angle = 90.0 + atan( -vect.x / vect.z ) * 180 / PI;
			else				// 3rd quarter
				angle = 270.0 - atan( -vect.x / -vect.z ) * 180 / PI;

		x = 1.0 - angle / 360.0;
		y = (vect.y + 1.0) / 2.0;	// x: 0..0.5 y: 0..1

//		Cout( Format( "vect x: {} y: {} z: {}, angle: {}, tex coord x: {} y: {}", vect.x, vect.y, vect.z, angle, x, y )).newline;
//		Cin.get();

		texCoords[ index ].set( x, y );
	}

	pMesh.fields["Vertex"].data.Vec3 = vertices;
	pMesh.fields["Normal"].data.Vec3 = normals;
	pMesh.fields["TexCoord"].data.Vec2 = texCoords;
	pMesh.fields["Index"].data.UInt = indexes;

	genMeshTangentSpace( pMesh );
	return pMesh;
}

//================================================================
/// cylinder
//================================================================
CResMesh genMeshCylinder( float rad, float hei,float detail )
{
	CResMesh pMesh = CResMesh( "Cylinder" );

	return pMesh;
}

//================================================================
/// dbg meshes
//================================================================
CResMesh genMeshLight()
{
	const int detals = 30;
	const int radius = 3;

	CResMesh pMesh = CResMesh( "dbgMeshLight" );
	pMesh.rendType = EMeshRenderType.mrt_line_loop;

	pMesh.fields["Index"].data.UInt.length = detals*2;
	pMesh.fields["Vertex"].data.Vec3.length = detals*2;

	for( int i = 0; i<detals; ++i)
	{
		pMesh.fields[ "Index" ].data.UInt[i] = i;
		pMesh.fields["Vertex"].data.Vec3[i] = Vector3f(cos(2*PI*i/detals)*2, sin(2*PI*i/detals)*2,0) * radius;
	}

	for( int i = detals; i<detals*2; ++i)
	{
		pMesh.fields[ "Index" ].data.UInt[i] = i;
		pMesh.fields["Vertex"].data.Vec3[i] = Vector3f(cos(2*PI*i/detals)*2,0, sin(2*PI*i/detals)*2) * radius;
	}

	return pMesh;
}

CResMesh genMeshByTexture( in CResTextureData hei, in int neiX, in int neiY )
in
{
	moonAssert( hei !is null, "hei is null!", __FILE__, __LINE__ );
}
body
{
    const int lod_0 = 70;
    const int lod_1 = 100;
    const int lod_2 = 10000;

	CResMesh pMesh = CResMesh( "procMeshLand" );
	pMesh.rendType = EMeshRenderType.mrt_fill_strip;
	pMesh.fields["Index"].data.UInt.length = 0;
	pMesh.fields["Vertex"].data.Vec3.length = 0;
	pMesh.fields["Normal"].data.Vec3.length = 0;

    uint indx = 0;
    int _fr, _to;
    bool aa = false;

    Vector3f calcNor(int i, int j)
    {
        Vector3f nor,vecA,vecB;
        nor.set(0,0,0);
        if( i < hei.width && j < hei.height)
        {
            vecA = Vector3f(10, 0, hei.readPixel(i,j).x - hei.readPixel(i+1,j).x);
            vecA.normalize;
            vecB = Vector3f(0, 10, hei.readPixel(i,j).x - hei.readPixel(i,j+1).x);
            vecB.normalize;
            nor += cp(vecA,vecB);
        }

        if( i >0 && j < hei.height)
        {
            vecA = Vector3f(0, 10, hei.readPixel(i,j).x - hei.readPixel(i,j+1).x);
            vecA.normalize;
            vecB = Vector3f(-10, 0, hei.readPixel(i,j).x - hei.readPixel(i-1,j).x);
            vecB.normalize;

            nor += cp(vecA,vecB);
        }

        if( i >0 && j >0 )
        {
            vecA = Vector3f(-10, 0, hei.readPixel(i,j).x - hei.readPixel(i-1,j).x);
            vecA.normalize;
            vecB = Vector3f(0, -10, hei.readPixel(i,j).x - hei.readPixel(i,j-1).x);
            vecB.normalize;

            nor += cp(vecA,vecB);
        }

        if( i < hei.width && j > 0)
        {
            vecA = Vector3f(0, -10, hei.readPixel(i,j).x - hei.readPixel(i,j-1).x);
            vecA.normalize;
            vecB = Vector3f(10, 0, hei.readPixel(i,j).x - hei.readPixel(i+1,j).x);
            vecB.normalize;

            nor += cp(vecA,vecB);
        }

        nor.normalize;
        return nor;
    }


	for( int i = max(0,neiX - lod_0); i < min(hei.width,neiX + lod_0)-1; i++)
	{
	    if ( aa )
	    {
	        _fr = max(0,neiY - lod_0);
	        _to = min(hei.height,neiY + lod_0);
	    } else
	    {
	        _fr = min(hei.height,neiY + lod_0);
	        _to = max(0,neiY - lod_0);
	    }
	    for( int j = _fr; j != _to;)
        {
            pMesh.fields["Index"].data.UInt ~= indx;
            pMesh.fields["Index"].data.UInt ~= indx+1;

            pMesh.fields["Vertex"].data.Vec3 ~= Vector3f(i*10, (j)*10, hei.readPixel(i,j).x);
            pMesh.fields["Vertex"].data.Vec3 ~= Vector3f((i+1)*10, (j)*10, hei.readPixel(i+1,j).x);


            pMesh.fields["Normal"].data.Vec3 ~= calcNor(i,j);
            pMesh.fields["Normal"].data.Vec3 ~= calcNor(i+1,j);


            indx+=2;
            if( aa ) ++j; else --j;
        }
        aa = !aa;

	}
/*
	for( int i = max(0,neiX - lod_1); i < min(hei.width,neiX + lod_1); i+=2)
        for( int j = max(0,neiY - lod_1); j < min(hei.height,neiY + lod_1); j+=2)
        {
            pMesh.fields["Index"].data.UInt ~= indx;
            pMesh.fields["Vertex"].data.Vec3 ~= Vector3f(i*10, j*10, hei.readPixel(i,j).x);
            ++indx;
        }


	for( int i = max(0,neiX - lod_2); i < min(hei.width,neiX + lod_2); i+=4)
        for( int j = max(0,neiY - lod_2); j < min(hei.height,neiY + lod_2); j+=4)
        {
            pMesh.fields["Index"].data.UInt ~= indx;
            pMesh.fields["Vertex"].data.Vec3 ~= Vector3f(i*10, j*10, hei.readPixel(i,j).x);
            ++indx;
        }
*/
	return pMesh;
}

CResMesh genMeshGeom()
{
	CResMesh pMesh = CResMesh( "dbgMeshGeom" );

	return pMesh;
}

CResMesh genMeshCamera()
{
	CResMesh pMesh = CResMesh( "dbgMeshCamera" );

	return pMesh;
}
